package cn.mju.tankfighterbackend.service.game

import cn.mju.tankfighterbackend.dto.game.GameData
import cn.mju.tankfighterbackend.dto.game.PlayerOptionDto
import cn.mju.tankfighterbackend.dto.game.SyncFrameDto
import cn.mju.tankfighterbackend.service.game.ClientMessageType.*
import cn.mju.tankfighterbackend.util.JsonUtil

enum class ClientMessageType {
    CLIENT_INIT, SYNC_FRAME, FRAME_REQUEST
}

enum class ServerMessageType {
    GAME_INIT, SYNC_FRAME
}

data class ClientMessageJsonBox(
    val messageType: ClientMessageType,
    val contextJson: String
)

data class ServerMessageJsonBox(
    val messageType: ServerMessageType,
    val contextJson: String
)

sealed class ClientGameMessage {

    /**
     * 表示用户连接到一场游戏
     */
    class InitMessage(
        val gameId: Long
    ) : ClientGameMessage()

    /**
     * 客户端发送一个当前同步帧的操作
     */
    class ClientFrameMessage(
        val gameId: Long,
        val frameIndex: Int,
        val option: PlayerOptionDto,

    ) : ClientGameMessage()

    /**
     * 客户端主动请求一个同步帧
     */
    class FrameRequestMessage(
        val gameId: Long,
        val frameIndices: Array<Int>
    ) : ClientGameMessage()

    companion object {
        fun resolve(ms: ClientMessageJsonBox): ClientGameMessage {
            return when (ms.messageType) {

                CLIENT_INIT -> JsonUtil.convertToObject<InitMessage>(ms.contextJson)
                SYNC_FRAME -> JsonUtil.convertToObject<ClientFrameMessage>(ms.contextJson)
                FRAME_REQUEST -> JsonUtil.convertToObject<FrameRequestMessage>(ms.contextJson)
            }
        }
    }
}

sealed class ServerGameMessage {
    companion object {
        fun packageInitMessage(i: GameInitMessage): ServerMessageJsonBox {
            return ServerMessageJsonBox(ServerMessageType.GAME_INIT, JsonUtil.convertToString(i))
        }

        fun packageFrameMessage(i: SyncFrameMessage): ServerMessageJsonBox {
            return ServerMessageJsonBox(ServerMessageType.SYNC_FRAME, JsonUtil.convertToString(i))
        }
    }

    class GameInitMessage(
        val playerId: Int,
        val gameData: GameData
    ) : ServerGameMessage()

    class SyncFrameMessage(
        val frames: Array<SyncFrameDto>
    ) : ServerGameMessage()
}

